import type { AsyncComputedOnCancel, AsyncComputedOptions } from '@vueuse/core';
import type { Ref } from 'vue';

export type ComputedLoadingReturn<T> = [Ref<T | undefined>, Readonly<Ref<boolean>>];

/**
 * 拓展 computedAsync 异步计算，多增加一个loading返回值
 * 返回值为[state,loading]
 */
export function computedLoading<T>(
  evaluationCallback: (onCancel: AsyncComputedOnCancel) => T | Promise<T>,
  initialState?: T,
  options?: AsyncComputedOptions,
): ComputedLoadingReturn<T> {
  const loading = ref(false);

  const evaluation = async (onCancel: AsyncComputedOnCancel) => {
    loading.value = true;
    try {
      loading.value = true;
      return await evaluationCallback(onCancel);
    } finally {
      loading.value = false;
    }
  };

  options ??= {};
  const shallow = options?.shallow ?? true;

  const state = computedAsync(evaluation, initialState, {
    ...options,
    shallow,
  });
  return [state, readonly(loading)];
}
